"""
API版本管理模块
"""

from fastapi import APIRouter, Request, HTTPException, status
from typing import Dict, Any, List, Optional
from datetime import datetime
import importlib
import inspect
from pathlib import Path

from .config import settings
from .exceptions import NotFoundError


class APIVersion:
    """API版本信息"""
    
    def __init__(
        self,
        version: str,
        title: str,
        description: str,
        is_stable: bool = False,
        deprecation_date: Optional[datetime] = None,
        sunset_date: Optional[datetime] = None,
        migration_guide: Optional[str] = None
    ):
        self.version = version
        self.title = title
        self.description = description
        self.is_stable = is_stable
        self.deprecation_date = deprecation_date
        self.sunset_date = sunset_date
        self.migration_guide = migration_guide
        self.endpoints = []
        self.created_at = datetime.utcnow()
    
    def add_endpoint(self, path: str, methods: List[str], description: str):
        """添加端点信息"""
        self.endpoints.append({
            "path": path,
            "methods": methods,
            "description": description
        })
    
    def is_deprecated(self) -> bool:
        """检查是否已弃用"""
        return self.deprecation_date is not None and self.deprecation_date <= datetime.utcnow()
    
    def is_sunset(self) -> bool:
        """检查是否已停用"""
        return self.sunset_date is not None and self.sunset_date <= datetime.utcnow()
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "version": self.version,
            "title": self.title,
            "description": self.description,
            "is_stable": self.is_stable,
            "is_deprecated": self.is_deprecated(),
            "is_sunset": self.is_sunset(),
            "deprecation_date": self.deprecation_date.isoformat() if self.deprecation_date else None,
            "sunset_date": self.sunset_date.isoformat() if self.sunset_date else None,
            "migration_guide": self.migration_guide,
            "created_at": self.created_at.isoformat(),
            "endpoints_count": len(self.endpoints),
            "endpoints": self.endpoints
        }


class APIVersionManager:
    """API版本管理器"""
    
    def __init__(self):
        self.versions: Dict[str, APIVersion] = {}
        self.default_version: Optional[str] = None
        self._load_versions()
    
    def _load_versions(self):
        """加载所有版本"""
        # 避免循环导入，延迟加载版本信息
        # 版本信息将在API路由初始化时注册
        pass
    
    def _load_version_module(self, module_name: str) -> Optional[APIVersion]:
        """加载版本模块"""
        # 避免循环导入，不在这里动态加载
        # 版本信息将在API路由初始化时注册
        return None
    
    def register_version(self, version: APIVersion):
        """注册版本"""
        self.versions[version.version] = version
        
        # 设置默认版本
        if self.default_version is None or version.is_stable:
            self.default_version = version.version
    
    def get_version(self, version: str) -> Optional[APIVersion]:
        """获取指定版本"""
        return self.versions.get(version)
    
    def get_all_versions(self) -> List[APIVersion]:
        """获取所有版本"""
        return list(self.versions.values())
    
    def get_active_versions(self) -> List[APIVersion]:
        """获取活跃版本（未停用的版本）"""
        return [v for v in self.versions.values() if not v.is_sunset()]
    
    def get_default_version(self) -> Optional[APIVersion]:
        """获取默认版本"""
        if self.default_version:
            return self.versions.get(self.default_version)
        return None
    
    def deprecate_version(
        self,
        version: str,
        deprecation_date: datetime,
        sunset_date: datetime,
        migration_guide: str = None
    ):
        """弃用版本"""
        if version in self.versions:
            api_version = self.versions[version]
            api_version.deprecation_date = deprecation_date
            api_version.sunset_date = sunset_date
            api_version.migration_guide = migration_guide
    
    def is_version_supported(self, version: str) -> bool:
        """检查版本是否支持"""
        api_version = self.versions.get(version)
        if not api_version:
            return False
        
        return not api_version.is_sunset()
    
    def get_version_compatibility(self, client_version: str) -> Dict[str, Any]:
        """获取版本兼容性信息"""
        if client_version not in self.versions:
            return {
                "compatible": False,
                "message": "不支持的API版本",
                "supported_versions": list(self.versions.keys())
            }
        
        client_api_version = self.versions[client_version]
        
        if client_api_version.is_sunset():
            return {
                "compatible": False,
                "message": f"API版本 {client_version} 已停用",
                "sunset_date": client_api_version.sunset_date.isoformat(),
                "migration_guide": client_api_version.migration_guide
            }
        
        if client_api_version.is_deprecated():
            return {
                "compatible": True,
                "deprecated": True,
                "message": f"API版本 {client_version} 已弃用，请升级到最新版本",
                "deprecation_date": client_api_version.deprecation_date.isoformat(),
                "sunset_date": client_api_version.sunset_date.isoformat(),
                "migration_guide": client_api_version.migration_guide
            }
        
        return {
            "compatible": True,
            "deprecated": False,
            "message": f"API版本 {client_version} 受支持"
        }


# 创建全局版本管理器
version_manager = APIVersionManager()


def versioned_api(version: str, title: str, description: str, is_stable: bool = False):
    """版本化API装饰器"""
    def decorator(router: APIRouter) -> APIRouter:
        # 创建版本信息
        api_version = APIVersion(
            version=version,
            title=title,
            description=description,
            is_stable=is_stable
        )
        
        # 自动添加端点信息
        for route in router.routes:
            if hasattr(route, 'path') and hasattr(route, 'methods'):
                api_version.add_endpoint(
                    path=route.path,
                    methods=list(route.methods),
                    description=route.summary or route.path
                )
        
        # 注册版本
        version_manager.register_version(api_version)
        
        return router
    
    return decorator


def get_version_info() -> APIVersion:
    """获取当前版本信息（用于版本模块）"""
    return APIVersion(
        version="1",
        title="Offline Language Player API v1",
        description="离线语言播放系统第一版API",
        is_stable=True
    )


def create_version_router() -> APIRouter:
    """创建版本管理路由"""
    router = APIRouter(prefix="/versions", tags=["versioning"])
    
    @router.get("/")
    async def list_versions():
        """列出所有API版本"""
        versions = version_manager.get_all_versions()
        return {
            "versions": [v.to_dict() for v in versions],
            "default_version": version_manager.get_default_version().version if version_manager.get_default_version() else None,
            "current_version": settings.VERSION
        }
    
    @router.get("/{version}")
    async def get_version_details(version: str):
        """获取指定版本详情"""
        api_version = version_manager.get_version(version)
        if not api_version:
            raise NotFoundError(f"API版本 {version} 不存在")
        
        return api_version.to_dict()
    
    @router.get("/{version}/compatibility")
    async def check_version_compatibility(version: str):
        """检查版本兼容性"""
        compatibility = version_manager.get_version_compatibility(version)
        return compatibility
    
    @router.get("/current")
    async def get_current_version():
        """获取当前版本信息"""
        return {
            "version": settings.VERSION,
            "api_version": version_manager.get_default_version().version if version_manager.get_default_version() else None,
            "project_name": settings.PROJECT_NAME,
            "description": settings.PROJECT_DESCRIPTION,
            "build_date": datetime.utcnow().isoformat()
        }
    
    return router


class APIVersionMiddleware:
    """API版本中间件"""
    
    async def __call__(self, request: Request, call_next):
        # 解析API版本
        version = self._extract_version_from_path(request.url.path)
        
        if version:
            # 检查版本支持
            if not version_manager.is_version_supported(version):
                raise HTTPException(
                    status_code=status.HTTP_410_GONE,
                    detail=f"API版本 {version} 不再受支持"
                )
            
            # 检查版本兼容性
            compatibility = version_manager.get_version_compatibility(version)
            if not compatibility.get("compatible", True):
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=compatibility["message"]
                )
            
            # 添加版本信息到请求状态
            request.state.api_version = version
            request.state.api_version_info = version_manager.get_version(version)
        
        # 添加API版本头
        response = await call_next(request)
        response.headers["API-Version"] = version or "unknown"
        
        if version and version_manager.get_version(version):
            api_version = version_manager.get_version(version)
            if api_version.is_deprecated():
                response.headers["API-Deprecated"] = "true"
                response.headers["API-Deprecation-Date"] = api_version.deprecation_date.isoformat()
                response.headers["API-Sunset-Date"] = api_version.sunset_date.isoformat()
        
        return response
    
    def _extract_version_from_path(self, path: str) -> Optional[str]:
        """从路径中提取版本号"""
        # 匹配 /api/v{number} 或 /api/v{number}.{number}
        import re
        match = re.search(r'/api/v(\d+(?:\.\d+)?)', path)
        return match.group(1) if match else None


def validate_api_version(version: str):
    """验证API版本依赖"""
    def dependency(request: Request):
        if not version_manager.is_version_supported(version):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"API版本 {version} 不受支持"
            )
        
        api_version = version_manager.get_version(version)
        if api_version.is_deprecated():
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"API版本 {version} 已弃用，请升级到最新版本"
            )
        
        return version
    
    return dependency
